/**
 *  工具类
 * created by Harry 2016-12-08 21:22:18
 */
public without sharing class Utils {
    //最小日期
    public static final String MIN_DATE_TIME = '2000-01-01 00:00:00';
    public static final String DATE_FORMAT_STR = 'yyyy-MM-dd';//默认日期文本格式
    public static final String DATETIME_FORMAT_STR = 'yyyy-MM-dd HH:mm:ss';//默认时间文本格式
    //记录类型缓存
    private static Map<String,Map<String,Id>> recordTypeCache = new Map<String,Map<String,Id>>();
    //初始化记录类型缓存
    static{
        List<RecordType> recordTypeList = [SELECT Id,DeveloperName,SobjectType,Name FROM RecordType];
        for(RecordType recordType : recordTypeList){
            Map<String,Id> tmpMap = null;
            if(null==recordTypeCache.get(recordType.SobjectType)){
                tmpMap = new Map<String,Id>();
            }else{
                tmpMap = recordTypeCache.get(recordType.SobjectType);
            }
            tmpMap.put(recordType.DeveloperName, recordType.Id);
            tmpMap.put(recordType.Name, recordType.Id);
            recordTypeCache.put(recordType.SobjectType, tmpMap);
        }
    }

    /*
       往log里面插入数据
     */
    public static void insertLog(String oper, Id uid, String msg) {
        Log__c l = new Log__c(
            Operation__c = oper,
            User__c = uid,
            ErrorMsg__c = msg
        );
        insert l;
    }

    /*
       往一个字符串input中的指定位置index插入字符串str
     */
    public static String insertString (String input,String str, Integer index){
        if(input==null||index<0 || index >input.length()){
            return input;
        }
        return input.substring(0, index) + str + input.substring(index,input.length());
    }

    /*
        往一个文本中添加换行符，在生成pdf时用
     */
    public static String wrapWordInPdf(String input, String character, Integer width){
        if(input==null || width<=0){
            return input;
        }
        Integer cnt = input.length()/width;
        String buf = input;
        String target = '</br>';
        for(Integer i = 1;i<=cnt;i++){
            buf = insertString(buf,character,width*i+character.length()*(i-1));
        }
        return buf;
    }
    /*
        日期转字符串
     */
    public static String date2string(Datetime dt){
        return null==dt?'':dt.format(DATETIME_FORMAT_STR);
    }
    /*
        日期转指定格式的字符串
     */
    public static String date2string(Datetime dt,String formatString){
        if(null==dt){
            return '';
        }
        return String.isEmpty(formatString)?date2string(dt):dt.format(formatString);
    }
    /*
        时间转字符串
     */
    public static String date2string(Date d){
        return null==d?'':Datetime.newInstance(d.year(), d.month(), d.day()).format(DATE_FORMAT_STR);
    }
    /*
        时间转指定格式的字符串
     */
    public static String date2string(Date d,String formatString){
        if(null==d){
            return '';
        }
        return String.isEmpty(formatString)?date2string(d):Datetime.newInstance(d.year(), d.month(), d.day()).format(formatString);
    }
    /*
        获取记录类型ID，参数name可以为developerName也可以是Name，sobjectType是对象名称
    */
    public static Id getRecordTypeIdByDevNameAndObjName(String name, String sobjectType){
        return recordTypeCache.get(sobjectType).get(name);
    }

    /*
        得到REST调用返回信息
        参数1：successed - 是否成功? 成功返为1,失败返回0
        参数2：errMessage - 要返回的信息
        参数3：ts - 最大时间戳
    */
    public static Map<String,String> getRestReturnMessage(Boolean successed,String errMessage,Datetime ts){
        Map<String,String> msg = new Map<String,String>();
        msg.put('result', successed?'1':'0');
        msg.put('result_msg',errMessage);
        msg.put('ts', ts.format(DATETIME_FORMAT_STR));
        System.debug('*** REST调用返回结果：' + JSON.serialize(msg));
        return msg;
    }
    public static RestReturnMessage getRestReturnMessage(Boolean successed,String errMessage){
        return getRestReturnMessage(successed,errMessage,new List<Map<String,String>>());
    }
    public static RestReturnMessage getRestReturnMessage(Boolean successed,String errMessage,List<Map<String,String>> data){
        if(data !=null && data.size()>0){
             return getRestReturnMessage(successed,errMessage,Datetime.now(),data);

        }else{
            return getRestReturnMessage(successed,errMessage,Datetime.now(),new List<Map<String,String>>());
        }
    }
    /*
        POST REST请求调用返回结果
        参数1：successed - 是否成功? 成功返为1,失败返回0
        参数2：errMessage - 要返回的信息
        参数3：ts - 本次查询数据的最大更新时间
        参数4：data - 结果数据集
        返回值：返回一个Map数组：
                {
                    "result":"0 OR 1 , 1表示成功，0表示失败", 
                    "result_msg":"要返回给调用者的信息",
                    "data":["结果数据集"]
                }
    */
    public static RestReturnMessage getRestReturnMessage(Boolean successed,String errMessage,Datetime ts,List<Map<String,String>> data){
        RestReturnMessage msg = new RestReturnMessage();
        msg.result = successed?'1':'0';
        msg.result_msg = errMessage;
        msg.ts = ts.format(DATETIME_FORMAT_STR);
        if(data != null){
            msg.data = data;
        }else{
            msg.data = new List<Map<String,String>>();
        }
        System.debug('*** REST调用返回结果：' + JSON.serialize(msg));
        return msg;
    }

    public static RestReturnMessage getRestReturnMessage(Boolean successed,String errMessage,Datetime ts,Map<String, List<Map<String,String>>> data){
        RestReturnMessage msg = new RestReturnMessage();
        msg.result = successed?'1':'0';
        msg.result_msg = errMessage;
        msg.ts = ts.format(DATETIME_FORMAT_STR);
        if(data != null){
            msg.dataMap = data;
        }else{
            msg.dataMap = new Map<String, List<Map<String,String>>>();
        }
        System.debug('*** REST调用返回结果：' + JSON.serialize(msg));
        return msg;
    }

    /*
        提交一个Request到服务器
        参数1：request - 要提交的request
        参数2：loopCount - 如果超时，自动循环的次数
        返回值：一个HttpResponse对象
    */
    public static HttpResponse postRequest(HttpRequest request,Integer loopCount){
        HttpRequest req = request;
        //设置提交超时时间(毫秒)
        req.setTimeout(60000);
        Http httpProtocol = new Http();
        HttpResponse response = null;
        //连接超时标记
        Boolean timeoutFlag = true;
        for(Integer i = 0 ; i < loopCount ; i++){
            if(!timeoutFlag){
                break;
            }
            timeoutFlag = false;
            try{
                if(Test.isRunningTest()){
                    response = new HttpResponse();
                    response.setHeader('Content-Type','application/x-www-form-urlencoded ; charset=GB2312');
                    response.setBody('result=0&confirm_time=2017-01-23 10:15:26&id=2001063&replys=[{"callmdn":"10656584854","mdn":"13929512501","content":"B","reply_time":"2017-01-01 16:37:31","id":"2001062"},{"callmdn":"10656485545","mdn":"18122266563","content":"A","reply_time":"2017-01-01 10:15:26","id":"2001063"}]');
                    response.setStatusCode(200);
                }else{
                    response = httpProtocol.send(req);
                }
                break;
            }catch(Exception ex){
                System.debug('*** 服务器连接超时错误信息：' + ex.getMessage());
                if(ex.getMessage() == 'Read timed out'){
                    timeoutFlag = true;
                    if(i == loopCount - 1 ){
                        System.debug('*** 重试' + loopCount + '次失败');
                        ex.setMessage(ex.getMessage() + ',重试' + loopCount + '次失败');
                        throw(ex);
                    }
                }else{
                    throw(ex);
                }
            }
        }
        return response;
    }
    /*
        描述：发送短信
        参数1：phone - 可以多个号码，每个号码间用逗号(,)分隔
        参数2：smsMessageText - 短信内容
        返回值 : 
    */
        /*
    @future(callout=true)
    public static void sendSmsMessage(String phone,String smsMessageText){
        if (System.Label.SendSMS_Flg == '0') {
            return;
        }
        
        //生成发送短信URL
        smsApi__c sms = smsApi__c.getValues('SMS_Setting');
        String url = sms.URL__c;
        url += '&SpCode=' + sms.SpCode__c ; //企业号
        url += '&LoginName=' + sms.LoginName__c ;//登录用户名
        url += '&Password=' + sms.Password__c; //登录用户密码
        url += '&SerialNumber=';//流水号,20位数字，唯一，与回执接口中的流水号对应，不传后面回执接口无法查询数据。
        url += '&ScheduleTime=';//计划发送时间
        url += '&UserNumber=' + phone;//电话号码，可以多个号码，每个号码间用逗号(,)分隔
        //必须编码为GB2312或GBK字符集
        url += '&MessageContent=' + EncodingUtil.urlEncode(smsMessageText,'GBK');
        //生成POST请求
        HttpRequest req = new HttpRequest(); 
        req.setEndpoint(url); 
        //POST数据到短信服务器，必须设置编码为GB2312或GBK,否则乱码
        req.setHeader('Content-Type','application/x-www-form-urlencoded ; charset=GB2312');
        req.setMethod('POST'); 
        //发送短信并取得返回结果
        HttpResponse res = Utils.postRequest(req,5); 
        //必须设置编码为GB2312或GBK，否则读取数据时会乱码
        res.setHeader('Content-Type','application/x-www-form-urlencoded ; charset=GB2312');
        String result = res.getBody();
        System.debug('*** 短信发送返回结果: ' + result);
    }*/
    /*
        描述：获取短信模板
        参数：templateName - 短信模板名
        返回值 : 短信模板内容
    */
        /*
    public static String getSMSTemplate(String templateName){
        List<SMSTemplate__c> smsTemp = [SELECT Id,Name,Body__c FROM SMSTemplate__c WHERE Name =: templateName];
        
        //if(smsTemp != null){
        if(smsTemp.size()>0){
            return smsTemp[0].Body__c;
        }
        else{
            System.debug('*** 获取短信模板【' + templateName + '】失败！'); 
            return '';
        }
    }*/
    /*
        描述：解析日期时间字符串
              如果成功则返加解析后的日期时间
              不成功则返回默认值"2000-01-01 00:00:00"
        参数：datetimeStr - 要解析的字符串
        返回：一个日期时间值
    */
    public static Datetime parseDatetime(String datetimeStr){
        Datetime dt ;
        try{
            dt = Datetime.valueOf(datetimeStr);
        }
        catch(Exception e){
            dt = Datetime.valueOf(MIN_DATE_TIME);
        }
        return dt;
    }
    /*
        描述：把个案的状态变化通知微信接口
        参数1：caseNumber - 个案Id
        参数2：status - 状态（1：新建，2：处理中，3：已升级，4：关闭，5：已派发，6：已分配）
        参数3：handler - 处理工程师
        返回值 : 
    */
    @future(callout=true)
    public static void postCaseStatusToWeiXin(String caseNumber,String status,String handler){
        //得到要传送的Json字符串
        String st = status.trim();
        System.debug('*** status参数: ' + status); 
        System.debug('*** caseNumber参数: ' + caseNumber); 
        System.debug('*** handler参数: ' + handler); 
       // st = st=='新建'?'1':st=='处理中'?'2':st=='已升级'?'3':st=='关闭'?'4':st=='已派发'?'5':st=='已分配'?'6':'1';
        String  json = '{"CaseNumber":"' + caseNumber + '","status":"' + st + '","handler":"' + handler + '"}';
        System.debug('*** POST JSON 数据: ' + json); 
        //取出微信接口配置信息(URL和密匙)
        //WeiXinAPI__c wx = WeiXinAPI__c.getValues('Weibo_Setting');
         WeiXinAPI__c wx = WeiXinAPI__c.getValues('delivery');

        String postURL = wx.URL__c;
         //String postURL = 'http://repair.maccura.com/maik-all/ws/Maike/delivery';
         System.debug(wx.Security__c);
         String security = wx.Security__c;
        
       
        
        //把要传递给微信接口的数据编码为MD5
        String md5 = EncodingUtil.convertToHex(Crypto.generateDigest('MD5',Blob.valueOf(json + security)));
        String strmd5 = 'json=' + json + '&sign=' + md5;
        String cipher = EncodingUtil.base64Encode(Blob.valueOf(EncodingUtil.urlEncode(strmd5,'UTF-8')));
        System.debug('*** POST MD5 参数: ' + cipher); 
        //生成POST请求
        postURL = postURL + '?cipher=' + cipher;
        HttpRequest req = new HttpRequest(); 
        req.setEndpoint(postURL); 
        //POST数据到微信接口，设置编码为GB2312,防止乱码
       // req.setHeader('Transfer-Encoding', 'chunked');
        req.setHeader('Content-Type','application/x-www-form-urlencoded ; charset=utf-8');
      // req.setHeader('Content-Length',String.valueOf(postURL.getChars().size()));
       // req.setBody('cipher=' + cipher);
        req.setCompressed(true);
        req.setMethod('POST'); 
        //发送数据并取得返回结果
        HttpResponse res = Utils.postRequest(req,3); 
        //设置编码为GB2312，防止读取数据时乱码
        res.setHeader('Content-Type','application/json;charset=UTF-8');
        res.setHeader('Transfer-Encoding', 'chunked');
        String result = res.getBody();

        System.debug('*** 微信接口返回结果: ' + result);
    }
    /***
        Blob hash = Crypto.generateDigest('MD5', Blob.valueOf(json+key));
        String md5 = EncodingUtil.convertToHex(hash);
        String strmd5 = 'json=' + json + '&sign=' + md5;
        String cipher = EncodingUtil.base64Encode(Blob.valueOf(strmd5));
    */

     

}